VPutSn = Put_Text_B_Length
Put_Text_Zero_Length = Put_Text_Zero_End





Check_Cursor_Over_Building:

 ld h, 0
 ld l, h
 ld (Current_Building), hl

	;This will check to see if the cursor is over a building, including one under
	;construction


 BIT Object_Ready_To_Add, (IY + flag)
 jp nz, Check_Building_On_Top_Of_Solid_Object



 call Find_Tile_On_Map



 ld a, (hl)		;Register A contains the tile we want to check, the tile
			;that the cursor is currently pointing to

 cp 126			;If the cursor is pointing to a building under
			;construction

 RES Cursor_Over_Wrench, (IY + flag + 1)
 jr z, Pre_Draw_Building_Info	;Special care must be taken
				;for a building under construction.
 cp 48				;There are 48 building tiles, 0 to 47.
				;Is the tile 47 or less?

 ret nc

 ld hl, Operation_Center 	;Check to see which building the tile
				;corresponds to.  The "Start tile" for the
				;Operation Center is at Operation Center + 1.

 ld b, 16	;16 buildings to check

 ld c, a	;Save the value of the tile
_

 	
 ld e, (hl)	;We save the value of the start tile, and see if the
		;current tile falls with in this range.

 push de

 ld de, 26

 add hl, de
 ld a, (hl)	;Building end tile
 or a
 sbc hl, de

 pop de

 inc hl

 ld d, a
 ld a, c

;See if the value in register a falls between E and D

 inc d

 cp e
 jr c, _
 cp d
 jr c, Draw_Building_Info



_
 
 ld de, 31
 add hl, de

 djnz   --_

 ret

 
Pre_Draw_Building_Info:

 SET Cursor_Over_Wrench, (IY + flag + 1) 


Draw_Building_Info:

 ld a, (hl)	;Building type

 ld bc, 4	
		
 add hl, bc	

 ld d, (hl)
 inc hl
 ld e, (hl)
 inc hl
 inc hl		;Points to text

 ld (Building_Total_HP), de
 ld d, a

 push hl	;We need to retrieve the building that the tile points to.
		;Save hl for later.

 ld b, 200	;Two hundred buildings to search
 ld hl, Structure_Locations
 ld a,  (TileX)


 ld c, d	;Now Register C contains the building type

 ld d, a

 ld a, (TileY)

 

 ld e, a

_

 push de
 

 ;In case we have the wrong building type

 BIT Cursor_Over_Wrench, (IY + Flag + 1)
 jr z, EmergencyLocalLabel9


 push bc

 ld a, (End_Of_List_Of_Buildings_Under_Construction)
 ld b, a

 push hl

 call Code_To_Call

EmergencyLocalLabel10:

 ld c, (hl)
 cp c
 jr z, EmergencyLocalLabel11

 call IncHL4

 djnz EmergencyLocalLabel10

 pop hl
 pop bc
 


 ld de, 4
 add hl, de
 
 pop de
 djnz -_
 ret

EmergencyLocalLabel11:

 pop hl
 push hl

 inc hl
 inc hl

 call Get_Building_ID_Collision

 

 ld (Structure_Under_Cursor), hl 

 inc hl
 ld e, (hl)
 
 pop hl
 pop bc
 ld c, e

 pop de
 push de




EmergencyLocalLabel9:

 push hl

 call Code_To_Call_2
  pop hl
 jr nz, ++_

 pop de
 push de
 

 ld a, (hl)
 cp d
 jr z, _

 ld a, c
 cp 3		;16 x 16 building
 jr z, ++_
 cp 2		;16 x 32 building
 jr z, ++_ 

 ld a, (hl)
 inc a
 cp d
 jr nz, ++_
_

 inc hl
 ld a, (hl)
 dec hl
 cp e
 jr nz, Continue_Check_Collision_One
 BIT Cursor_Over_Wrench, (IY + flag + 1) 
 jr nz,Building_Under_Cursor_Found_PopDE

 ld (Structure_Under_Cursor), hl
 jr Building_Under_Cursor_Found_PopDE

Continue_Check_Collision_One:

 call Code_To_Call_3
 jr z, _
 cp 1
 jr z, _

 ld a, d
 inc a
 cp e
 jr nz, _

 BIT Cursor_Over_Wrench, (IY + flag + 1) 
 jr nz,Building_Under_Cursor_Found_PopDE

 ld (Structure_Under_Cursor), hl
 jr Building_Under_Cursor_Found_PopDE

_

 call IncHL4

 pop de
 djnz ---_

 ret

Building_Under_Cursor_Found_PopDE:

 pop de

Building_Under_Cursor_Found

 push hl	;Save where the building is so we can retrieve the HP after
 		;putting the info box on the screen

 ld hl, InfoBox
 ld de, plotsscreen + (49*12)
 ld bc, 15*12
 ldir

_ 


 pop hl		;hl points to the beginning of the building.  Retrieve the HP.

 push hl
 inc hl
 inc hl		;Get HP

 ld a, (hl)
 and %00001111
 ld d, a
 inc hl
 ld e, (hl)

 
 ld hl, 51 * 256 + 2
 ld (penCol), hl 



 ;We needed to go through all this to get the HP.  However, it is
 ;now very possible that we should not display the name of the building on the first
 ;line of the text box.  We display the name if the builidng is being constructed or if the building
 ;is under normal circumstances.  If the building is CONSTRUCTING something, we display (in the first
 ;line) what the building is constructng.


 pop bc
 pop hl

 push de	;Saves the HP

 BIT Cursor_Over_Wrench, (IY + flag + 1) 
 jr nz, EmergencyLocalLabel13

 ld b, h		;Save the value of HL, JUST IN CASE we need to display the building name
 ld c, l		;rather than what is being constructed

 ;Is this a refinery constructing a processing unit?  It requires special code to see if it
 ;actually is.

 call Get_To_Structure_Tags_From_Structure_Locations

 ;HL contains the data for the partictual refinery.  If the first byte is greater than
 ;the second byte, a processing unit is being built.

 ld a, (hl)

 inc hl

 cp (hl)

 ;If the two bytes are equal, the cursor is simply pointing to a normally-operating refinery
 
 jr nz, Refinery_Building_Processing_Unit

 ld h, b
 ld l, c

 jr _

Refinery_Building_Processing_Unit:


;Stores the number of PUs qued by taking the number of processing units the player
;WANTS to have and subtracting the number actually built

 ld e, (hl)
 dec hl
 ld a, (hl)

 sub e

 ld d, 0
 ld e, a	

 push de



 ld hl, cleartext
 ld de, ASCIINumber
 ld bc, 6
 ldir

 pop de


 ld hl, 51 * 256 + 80
 ld (penCol), hl 

 call bintobcd16

 ld hl, ASCIINumber

 Call Put_Text_Zero_End

 ld hl, 51 * 256 + 2
 ld (penCol), hl

 ld hl, Text_Building_Processing_Unit
 ld b, 15
 jr ++_
 


EmergencyLocalLabel13:

 ld hl, (Structure_Under_Cursor)

 ld de, 5
 add hl, de

 ld d, (hl)
 inc hl
 ld e, (hl)
 inc hl
 inc hl

 ld (Building_Total_HP), de
 

_




 ld b, 18

_
 call VPutSN



 ld hl, 57*256+2		;Friendly or not?
 ld (penCol), hl
 ld b, 8
 ld hl, Friendly_Unit
 call VPutSN

 ld hl, 57*256+60		;"HP:"
 ld (penCol), hl
 ld b, 3
 ld hl, HP_Text
 call VPutSN


 ;Now display the hp

_

Draw_Different_HP:

 ld hl, zerotext
 ld de, ASCIINumber
 ld bc, 6
 ldir
 pop de
 push de


 call bintobcd16
 ld hl, 57*256+72		
 ld (penCol), hl
 
 ld hl, ASCIINumber

 Call Put_Text_Zero_End
 
 pop hl
 ex de, hl
 
 ld hl, (Structure_Under_Cursor)
 inc hl
 inc hl

 ld a, (hl)
 and %11110000
 
 cp $50
 jr z, +_

 ex de, hl
 call Multiply_HP_By_32



 ld de, (Building_Total_HP)
 jr ++_

 ;IF a processing unit is being constructed, we need to adjust the Total HP
 ;so that the correct progress bar displays correctly.

_
 ex de, hl
 push af
 push hl
 

 call Get_To_Structure_Tags_From_Structure_Locations

 ;Display the number of processing units the building has

 inc hl

 ld a, (hl)
 dec hl
 cp (hl)

 jr nz, No_Draw_Number_Of_PUs

 push hl



 ld hl, zerotext
 ld de, ASCIINumber
 ld bc, 6
 ldir

 ld d, 0
 ld e, a

 call bintobcd16
 ld hl, 51*256+61		
 ld (penCol), hl

 ld hl, ASCIINumber

 call Put_Text_Zero_End
 pop hl

No_Draw_Number_Of_PUs:


 ;Now HL points to the number of processing units we WANT to have (but might not have)

 ld a, (hl)
 or a

 jr nz, EmergencyLocalLabel16



 pop hl
 pop af


 call Multiply_HP_By_32

 ld de, (Building_Total_HP)


 jr _

EmergencyLocalLabel16:

 inc hl ;HL points to the number of processing units we actually have.  We need this to display
	;the progress bar for health correctly.

 cp (hl)	;If no processing units are being built, we display the total HP of the current processing unit.
		
 
 jr nz, EmergencyLocalLabel15


 inc hl		
 ld a, (hl)

 pop hl
 ld h, 0
 ld l, a

 pop af

 call Multiply_HP_By_32

 ld de, 50

 jr +_



EmergencyLocalLabel15:	;For a processing unit that is being built


 ld a, (hl)
 inc a

 ld de, 50
 call Multiply_DE_By_A
 
 ex de, hl

 or a
 pop hl
 sbc hl, de
 
 ld de, 50

 pop af

 call Multiply_HP_By_32
 


_

 call Divide_AC_By_DE

 ld d, a
 ld e, c

 ld a, 96


 call Multiply_DE_By_A

 ex de, hl

 srl d \ rr e
 srl d \ rr e
 srl d \ rr e
 srl d \ rr e
 srl d \ rr e




 ld d, e
 ld e, 0
 
 push de

 ld a, 12
 ld (Sprite_Width), a
 ld b, 5

 ld a, 0
 ld l, 0

 ld ix, Progress_Health_Bar
 call Put_Sprite_Overwrite

 pop de

 ld a, d
 and %11111000
 rrca \ rrca \ rrca
 ld c, a
 ld a, 12
 sub c

 ld b, 5
 ld c, a

 ld ix, Progress_Bar_Clear
 ld iy, Progress_Bar_Clear

 call LargeClippedSprite

 ld iy, flags
 ret

ClearText:

 .db "//////"


Divide_AC_By_DE:
   ld	hl, 0
   ld	b, 16

_loop:
   scf \ rl c

   rla
   adc	hl, hl
   sbc	hl, de
   jr	nc, $+4
   add	hl, de
   dec	c
   
   djnz	_loop
   
   ret

Progress_Health_Bar:

	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %00110000,%11000011,%00001100,%00110000,%11000011,%00001100,%00110000,%11000011,%00001100,%00110000,%11000011,%00001101
	.db %01100001,%10000110,%00011000,%01100001,%10000110,%00011000,%01100001,%10000110,%00011000,%01100001,%10000110,%00011001
	.db %11000011,%00001100,%00110000,%11000011,%00001100,%00110000,%11000011,%00001100,%00110000,%11000011,%00001100,%00110001
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111

Progress_Bar_Clear:

	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111


Get_Building_ID_Collision:

 ld a, (hl)

 and %11110000
 rra \ rra \ rra \ rra
 ld e, a
 ld d, 0
 ld a, 32
 Call Multiply_DE_By_A
 ex de, hl
 ld hl, Operation_Center
 add hl, de

 ret


Check_Building_On_Top_Of_Solid_Object:


;When deciding where to put a building, this sub will
;determine if one would place a building on 
;a solid object, such as a rock, tree or another building


;Register A will hold the building that the user
;is currently deciding where to place

	ld a, (BuildingSelected)

;We need to know how many tiles the building has,
;so that we know how many places to check for solid objects
;under the building.  We find the building being built,
;and retrive whether it's 16 x 16, 32 x 32, etc.

	ld de, 32
	
	call Multiply_DE_By_A

	ld de, Operation_Center
	add hl, de

	inc hl	;HL now points to the building type

	ld c, (hl)	;Register C contains the building
			;type.  I used register C
			;because it's traditional in this
			;program, the reason being that
			;it's partner (B), DE and HL
			;are often tied up.

;We need to adjust the values of the cursor to
;quickly detect collision.  The program will
;store the values temporarily into IX.

	ld ix, (Select_Cursor_X)

;Depending on the building type, we will need to check
;for collision from several tiles.  We will use
;DJNZ and register for B.  Using C, which contains the
;building type, we find an appropriate value for register
;B.

	

	ld a, c
	or a
	jr nz, _
	ld b, 4
	jr +++_
_
	cp 3
	jr nz, _
	ld b, 1
	jr ++_

_
	ld b, 2


_

Check_Tile_Under_Cursor_For_Collision:
	



	;Now that we know how big the building is,
	;look at where the cursor is, and see if any
	;collidable tiles fall under the building.

	;We look at the tile under the cursor, and in some
	;cases, surrounding tiles.

	push bc
 	call Find_Tile_On_Map

	;HL contains the tile we want to check for
	;solidity

	
	ld d, h
	ld e, l

	ld a, (hl)	;In case we need to check collision
			;for refineries (and thus require special code),
			;we save the value for the current tile.


	ld bc, MapData + 2
	or a
	sbc hl, bc

	ld b, a

	;Refineries can only be built on top of crystal deposits.  We
	;use a special collision function to test for refineries.

	ld a, (BuildingSelected)
	cp 5		;Refinery
	jr nz, _

	ld a, b

;This part will be optimized later, but right now, crystals are here, there
;and everywhere in the tileset

	cp 93
	jr z, Building_Can_Be_Placed
	cp 94
	jr z, Building_Can_Be_Placed
	cp 109
	jr z, Building_Can_Be_Placed
	cp 110
	jr z, Building_Can_Be_Placed
	jr Building_Cannot_Be_Placed


_
	

	;Divide HL by 2, and store the value into DE.
	;This will get to the proper tile conditions.

	srl h \ rr l
	
	ld bc, MapTileConditions
	add hl, bc

	pop bc


	ex de, hl	




	;Now hl points to the tile that the cursor 
	;is over.  DE points to the pair of tiles,
	;one of which the tile in hl points to.

	;Find out if the tile hl points to is
	;refered to in the first nibble of DE or the
	;last nibble of DE

	BIT 0, l
	
	jr nz, _
	jr Check_First_Pair_Tile_Over_Building
	jr ++_

_	
	jr Check_Second_Pair_Tile_Over_Building

_

Check_Solid_Continue:

	dec b


	;If b = 0, all tiles have passed,
	;and the building can be placed in the spot.

	jr z, Building_Can_Be_Placed

	ld a, b

	cp 3
	jr z, Adjust_Cursor_Check_Solid_For_32x32

	cp 2
	jr z, Adjust_Cursor_Check_Solid_For_16x32

;B = 1
	ld a, c
	cp 1
	jr z, Adjust_Cursor_Check_Solid_For_32x32
	or a
	jr z, Adjust_Cursor_Check_Solid_For_32x32


	
	;We adjust the cursor position to search
	;the other tiles, seeing if collision can occur.
	;We add H to Cursor_X and L to Cursor_Y.

Adjust_Cursor_Check_Solid_Other:

	ld h, 0
	ld l,16
	jr Change_Cursor_To_Check_Solid	


Adjust_Cursor_Check_Solid_For_32x32:

	
	ld h, 16
	ld l, 0
	jr Change_Cursor_To_Check_Solid

Adjust_Cursor_Check_Solid_For_16x32:

	ld l, 16
	ld h, -16

Change_Cursor_To_Check_Solid:

	ld a, (Cursor_X)
	add a, h
	ld (Cursor_X), a

	ld a, (Cursor_Y)
	add a, l
	ld (Cursor_Y), a

	jr Check_Tile_Under_Cursor_For_Collision


Check_First_Pair_Tile_Over_Building:


	ld a, (de)

	and %00010000

	jr z, Check_Solid_Continue

;Since the building cannot be placed, let the player
;know that by drawng a building in inverse colors.

	jr Building_Cannot_Be_Placed



Check_Second_Pair_Tile_Over_Building:


	ld a, (de)

	and %00000001

	jr z, Check_Solid_Continue

;Since the building cannot be placed, let the player
;know that by drawng a building in inverse colors.

Building_Cannot_Be_Placed:



	ld (Select_Cursor_X), IX

	BIT Building_Over_Solid_Object, (IY + flag + 2)
	jr nz, _

	SET Building_Over_Solid_Object, (IY + flag + 2)
	call Invert_Building_Cursor

_
	ret

Building_Can_Be_Placed:



	ld (Select_Cursor_X), IX

	BIT Building_Over_Solid_Object, (IY + flag + 2)
	jr z, _

	RES Building_Over_Solid_Object, (IY + flag + 2)
	call Invert_Building_Cursor

_
	ret


Invert_Building_Cursor:

	ld b, 128	;The cursor buffer is only 128 bytes.
			;We need to invert all those bytes.

	ld hl, Cursor_Building_Space + 3

_

	ld a, (hl)
	cpl
	ld (hl), a
	inc hl
	djnz -_
	
	ret



Code_To_Call:

 or a
 ld de, Structure_Locations
 sbc hl, de
 ld a, l
 srl h \ rra
 srl h \ rra

 ld hl, List_Of_Buildings_Under_Construction
 
 ret

IncHL4:

 inc hl
 inc hl
 inc hl
 inc hl
 ret

Code_To_Call_2:

 inc hl
 inc hl
 call Get_Building_ID_Collision

 inc hl
 ld a, c
 cp (hl)


 ret

Code_To_Call_3:

 ld d, a
 ld a, c
 cp 3

 ret


Multiply_HP_By_32:

 ld a, h
 ld c, l

  sla c \ rla
  sla c \ rla
  sla c \ rla
  sla c \ rla
  sla c \ rla

 ret
